#ifndef  __HEAPARRAY_H__
#define __HEAPARRAY_H__
#include <stdexcept>

template <typename T>
class HeapArray
{
private:
	int m_len;
	T* m_pointer;

	HeapArray(int len);
	bool Constructor(int len);
public:
	~HeapArray();
	static HeapArray<T>* NewInstance(int len);
	int length() const;
	bool set(int index, T value);
	bool get(int index, T& value);
	T& operator [] (int index);
	T operator [] (int index) const;
	HeapArray<T>& self();
	const HeapArray<T>& self() const;
};

template <typename T>
HeapArray<T>::HeapArray(int len)
{
	m_len = len;
}

template <typename T>
bool HeapArray<T>::Constructor(int len)
{
	m_pointer = new T[len];
	return m_pointer != NULL;
}

template <typename T>
HeapArray<T>::~HeapArray()
{
	delete[]m_pointer;
}

template <typename T>
HeapArray<T>* HeapArray<T>::NewInstance(int len)
{
	HeapArray<T>* ret = new HeapArray<T>(len);
	if (!(ret && ret->Constructor(len)))
	{
		delete ret;
		ret = 0;
	}

	return ret;
}

template <typename T>
HeapArray<T>& HeapArray<T>::self()
{
	return *this;
}

template <typename T>
const HeapArray<T>& HeapArray<T>::self() const
{
	return *this;
}

template <typename T>
int HeapArray<T>::length() const
{
	return m_len;
}

template <typename T>
bool HeapArray<T>::set(int index, T value)
{
	bool ret = (0 <= index && length() > index);
	if (ret)
		m_pointer[index] = value;
	return ret;
}

template <typename T>
bool HeapArray<T>::get(int index, T& value)
{
	bool ret = (0 <= index && length() > index);
	if (ret)
		value = m_pointer[index];
	return ret;
}

template <typename T>
T& HeapArray<T>::operator[] (int index)
{
	if ((0 <= index && length() > index))
	{
		return m_pointer[index];
	}
	else
	{
		throw out_of_range("T& HeapArray<T>::operator[] (int index)");
	}
	
}

template <typename T>
T HeapArray<T>::operator[] (int index) const
{
	if ((0 <= index && length() > index))
	{
		return m_pointer[index];
	}
	else
	{
		throw out_of_range("T HeapArray<T>::operator[] (int index) const");
	}
}





#endif